package com.fuchuang.seckillsystem.config;

import com.fuchuang.seckillsystem.entity.MyUserDetails;
import com.fuchuang.seckillsystem.utils.JsonWebTokenUtils;
import com.fuchuang.seckillsystem.utils.ResponseUtils;
import com.fuchuang.seckillsystem.vo.LoginToken;
import com.fuchuang.seckillsystem.vo.RespBean;
import com.fuchuang.seckillsystem.vo.RespBeanEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * spring security处理器
 */
@Configuration
public class SecurityHandlerConfig {
    
    @Autowired
    private JsonWebTokenUtils jsonWebTokenUtils;
    
    
    /**
     * 登陆成功，返回Token
     */
    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> {
            Map<String, Object> map = new HashMap<>();
            //获取登录用户信息
            MyUserDetails userDetails = (MyUserDetails) authentication.getPrincipal();
            //生成token数据
            String token = jsonWebTokenUtils.generateToken(userDetails.getUsername());
            String refreshToken = jsonWebTokenUtils.generateRefreshToken(userDetails.getUsername());
            //token过期时间
            Date expireTime = new Date(System.currentTimeMillis() + jsonWebTokenUtils.getExpiration());
            //渲染返回 token 和用户角色信息给前端
            LoginToken loginToken = new LoginToken(token, refreshToken, expireTime);
            map.put("loginToken", loginToken);
            map.put("roles", userDetails.getAuthorities());
            ResponseUtils.result(response, RespBean.success(map));
        };
    }
    
    /**
     * 登陆失败
     */
    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) -> {
            if (exception instanceof UsernameNotFoundException) {
                ResponseUtils.result(response, RespBean.error(RespBeanEnum.USERNAME_NOT_EXIST_ERROR));
            } else if (exception instanceof BadCredentialsException) {
                ResponseUtils.result(response, RespBean.error(RespBeanEnum.PASSWORD_ERROR));
            } else {
                ResponseUtils.result(response, RespBean.error(RespBeanEnum.LOGIN_ERROR));
            }
        };
    }
    
    /**
     * 未登录，返回401
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, authException) -> ResponseUtils.result(response, new RespBean(401, "请先登录！", null, new Date(), System.currentTimeMillis()));
    }
    
    /**
     * 登录了，权限不足 返回403
     */
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (httpServletRequest, response, e) -> ResponseUtils.result(response, new RespBean(403, "无权限访问！", null, new Date(), System.currentTimeMillis()));
    }
    
    /**
     * 退出处理
     */
    @Bean
    public LogoutSuccessHandler logoutSussHandler() {
        return (request, response, authentication) -> {
            //前端直接删除存储的token和refreshToken
            ResponseUtils.result(response, new RespBean(200, "登出成功", null, new Date(), System.currentTimeMillis()));
        };
    }
}
